/*
Copyright (C) 2021-2025 Casa Xu (also Zhiyan Xu) from HIT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/*
 * LOS_CIOMPCam.c
 *
 *  Created on: 2022年8月7日
 *      Author: 64435
 */

#include "LOS_CIOMPCam.h"

uint8_t TMPACK_CIOMPCam[45];

/** @fn void LOS_CIOMPCam_Snap()
*   @brief 高分相机拍照指令
*   @note 指令码：0x11
*/
void LOS_CIOMPCam_Snap()
{
    uint8_t data[5]={0xEB, 0x90, 0x22, 0x11, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = data[2] + data[3];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,5);
}

/** @fn void LOS_CIOMPCam_SetMode(uint8_t checkmode, uint8_t cammode, uint8_t checkimg, uint8_t expomode)
*   @brief 高分相机成像模式设置指令
*   @param[in] checkmode 0X11: CMOS成像 0x55: CMOS自校
*   @param[in] cammode 相机模式:  0x44:成像模式 0x66:图像模式 0x88:推扫模式
*   @param[in] checkimg 焦面模组自校图形: 0x55:渐变灰阶 0xAA:棋盘格
*   @param[in] expomode 曝光模式: 0x55:常规曝光 0xAA:最大曝光  
*   @note 指令码：0x22
*/
void LOS_CIOMPCam_SetMode(uint8_t checkmode, uint8_t cammode, uint8_t checkimg, uint8_t expomode)
{
    uint8_t data[9]={0xEB, 0x90, 0x22, 0x22, 0x11, 0x66, 0x55, 0x55, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = checkmode;
    data[5] = cammode;
    data[6] = checkimg;
    data[7] = expomode;
    data[8] = data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,9);
}

/** @fn void LOS_CIOMPCam_Stop()
*   @brief 高分相机停止拍照指令
*   @note 指令码：0x33
*/
void LOS_CIOMPCam_Stop()
{
    uint8_t data[5]={0xEB, 0x90, 0x22, 0x33, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = data[2] + data[3];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,5);
}

/** @fn void LOS_CIOMPCam_SetTime(uint32_t second)
*   @brief 高分相机秒时间设置指令
*   @param[in] second 星务时间
*   @note 指令码：0x77
*/
void LOS_CIOMPCam_SetTime(uint32_t second)
{
    uint8_t data[9]={0xEB, 0x90, 0x22, 0x77, 0x11, 0x66, 0x55, 0x55, 0x00};
    uint32_t setsec = second;
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    memcpy(&data[4], &setsec, 4);
    data[8] = data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,9);
}

/** @fn void LOS_CIOMPCam_PPSSelect(uint8_t PPS)
*   @brief 高分相机秒脉冲选择指令
*   @param[in] PPS 0X11:主份 0X22:备份 0X44:自身
*   @note 指令码：0x88
*/
void LOS_CIOMPCam_PPSSelect(uint8_t PPS)
{
    uint8_t data[6]={0xEB, 0x90, 0x22, 0x88, 0x00, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = PPS;
    data[5] = data[2] + data[3] + data[4];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,6);
}

/** @fn void LOS_CIOMPCam_SetGain(uint8_t Gain)
*   @brief 高分相机增益设置指令
*   @param[in] Gain
*   @note 指令码：0xA1
*/
void LOS_CIOMPCam_SetGain(uint8_t Gain)
{
    uint8_t data[6]={0xEB, 0x90, 0x22, 0xA1, 0x24, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = Gain;
    data[5] = data[2] + data[3] + data[4];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,6);
}

/** @fn void LOS_CIOMPCam_SetFramePeriod(uint32_t Period)
*   @brief 高分相机帧周期设置指令
*   @param[in] Period 帧周期
*   @note 指令码：0xA3
*/
void LOS_CIOMPCam_SetFramePeriod(uint32_t Period)
{
    uint8_t data[9]={0xEB, 0x90, 0x22, 0xA3, 0x11, 0x66, 0x55, 0x55, 0x00};
    uint32_t period = Period;
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    memcpy(&data[4], &period, 4);
    data[8] = data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,9);
}

/** @fn void LOS_CIOMPCam_SetExposureTime(uint32_t Time)
*   @brief 高分相机曝光时间设置指令
*   @param[in] Time 帧周期
*   @note 指令码：0xA4
*/
void LOS_CIOMPCam_SetExposureTime(uint32_t Time)
{
    uint8_t data[9]={0xEB, 0x90, 0x22, 0xA4, 0x11, 0x66, 0x55, 0x55, 0x00};
    uint32_t time = Time;
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    memcpy(&data[4], &time, 4);
    data[8] = data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,9);
}

/** @fn void LOS_CIOMPCam_SetCMOSDirection(uint8_t Direction)
*   @brief 高分相机CMOS输出方向设置指令
*   @param[in] Direction
*   @note 指令码：0xA5
*/
void LOS_CIOMPCam_SetCMOSDirection(uint8_t Direction)
{
    uint8_t data[6]={0xEB, 0x90, 0x22, 0xA5, 0x00, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = Direction;
    data[5] = data[2] + data[3] + data[4];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,6);
}

/** @fn void LOS_CIOMPCam_GetState()
*   @brief 高分相机状态查询指令
*   @note 指令码：0xA6
*/
void LOS_CIOMPCam_GetState()
{
    uint8_t data[5]={0xEB, 0x90, 0x22, 0xA6, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = data[2] + data[3];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,5);
    STA_CIOMPCam.HL_TXF = 1;
}

/** @fn void LOS_CIOMPCam_SetVFirstLine(uint16_t Line)
*   @brief 高分相机视频模式起始行设置指令
*   @param[in] Line
*   @note 指令码：0xA7
*/
void LOS_CIOMPCam_SetVFirstLine(uint16_t Line)
{
    uint8_t data[7]={0xEB, 0x90, 0x22, 0xA7, 0x00, 0x00, 0x00};
    uint16_t line = Line; 
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    memcpy(&data[4], &line, 2);
    data[6] = data[2] + data[3] + data[4] + data[5];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,7);
}

/** @fn void LOS_CIOMPCam_SetSFirstLine(uint16_t Line)
*   @brief 高分相机推扫模式起始行设置指令
*   @param[in] Line
*   @note 指令码：0xA8
*/
void LOS_CIOMPCam_SetSFirstLine(uint16_t Line)
{
    uint8_t data[7]={0xEB, 0x90, 0x22, 0xA8, 0x00, 0x00, 0x00};
    uint16_t line = Line; 
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    memcpy(&data[4], &line, 2);
    data[6] = data[2] + data[3] + data[4] + data[5];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,7);
}

/** @fn void LOS_CIOMPCam_SelectBit(uint8_t Bit)
*   @brief 高分相机位选指令
*   @param[in] Bit
*   @note 指令码：0xA9
*/
void LOS_CIOMPCam_SelectBit(uint8_t Bit)
{
    uint8_t data[6]={0xEB, 0x90, 0x22, 0xA9, 0x00, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = Bit;
    data[5] = data[2] + data[3] + data[4];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,6);
}

/** @fn void LOS_CIOMPCam_FPNCorrection(uint8_t par1)
*   @brief 高分相机FPN校正指令
*   @param[in] par1 0x55:使能 0xAA:禁用
*   @note 指令码：0xB2
*/
void LOS_CIOMPCam_FPNCorrection(uint8_t par1)
{
    uint8_t data[7]={0xEB, 0x90, 0x22, 0xB2, 0x00, 0x00, 0x00}; 
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = par1;
    data[5] = 0x00;
    data[6] = data[2] + data[3] + data[4] + data[5];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,7);
}

/** @fn void LOS_CIOMPCam_SDPCCorrection(uint8_t par1)
*   @brief 高分相机SDPC校正指令
*   @param[in] par1 0x55:使能 0xAA:禁用
*   @note 指令码：0xB3
*/
void LOS_CIOMPCam_SDPCCorrection(uint8_t par1)
{
    uint8_t data[7]={0xEB, 0x90, 0x22, 0xB3, 0x00, 0x00, 0x00}; 
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = par1;
    data[5] = 0x00;
    data[6] = data[2] + data[3] + data[4] + data[5];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,7);
}

/** @fn void LOS_CIOMPCam_Config(uint8_t par1, uint8_t par2)
*   @brief 高分相机配置指令
*   @param[in] par1 0x44:加载出厂配置 0x66:加载用户配置 0x88:存储用户配置
*   @param[in] par2 用户配置ID 0X00~0X04
*   @note 指令码：0xB5
*/
void LOS_CIOMPCam_Config(uint8_t par1, uint8_t par2)
{
    uint8_t data[7]={0xEB, 0x90, 0x22, 0xB5, 0x00, 0x00, 0x00}; 
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = par1;
    data[5] = par2;
    data[6] = data[2] + data[3] + data[4] + data[5];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,7);
}

/** @fn void LOS_CIOMPCam_ProgressionSet(uint8_t par1)
*   @brief 高分相机推扫模式级数设置指令
*   @param[in] par1 1~8
*   @note 指令码：0xAA
*/
void LOS_CIOMPCam_ProgressionSet(uint8_t par1)
{
    uint8_t data[6]={0xEB, 0x90, 0x22, 0xAA, 0x00, 0x00};
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    data[4] = par1;
    data[5] = data[2] + data[3] + data[4];
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,6);
}

/** @fn void LOS_CIOMPCam_AuxiliaryData(uint8_t* par)
*   @brief 高分相机平台辅助数据指令
*   @param[in] par 平台辅助数据，512字节
*   @note 指令码：0xBB
*/
void LOS_CIOMPCam_AuxiliaryData(uint8_t* par)
{
    uint8_t data[517];
    uint16_t cnt = 0;
    data[0] = 0xEB;
    data[1] = 0x90;
    data[2] = 0x22;
    data[3] = 0xBB;
    data[516] = 0x00;
    LOS_MAX14830_ResetFIFO(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort);
    memcpy(&data[4], par, 512);
    for (cnt = 2; cnt < 516; cnt++)
    {
        data[516] += data[cnt];
    }
    LOS_MAX14830_WriteBytes(CIOMPCAM_MAXNUM, CIOMPCAM_MAXPort, data ,517);
}


/** @fn void LOS_CIOMPCam_CallBack(uint8_t* msg)
*   @brief 高分相机遥测处理函数
*   @param[in] msg 遥测包内容，39字节
*   @note 
*/
void LOS_CIOMPCam_CallBack(uint8_t* msg)
{
    uint8_t cnt = 0;
    uint8_t sum = 0;
    memcpy(STA_CIOMPCam.TMMSG, &msg[2], 29);
    memcpy(&TMPACK_CIOMPCam[0], &LOS_Time_SecFromBoot, 4);
    memcpy(&TMPACK_CIOMPCam[4], &LOS_Time_MilSec, 2);
    memcpy(&TMPACK_CIOMPCam[6], &LOS_Time_Sec, 4);
    memcpy(&TMPACK_CIOMPCam[10], &msg[4], 35);

    for (cnt=0;cnt<38;cnt++)
    {
        sum += msg[cnt];
    }

    if (sum == msg[38]) //校验和通过
    {
       STA_CIOMPCam.sumflag = 0XAA;
    }
    else //校验和不通过
    {
       STA_CIOMPCam.sumflag = 0X55;
    }
}

void LOS_CAM_PWROn()
{
    STA_CIOMPCam.CMD = 1;
    LOS_EPS_Switch(17, SWITCH_ON);
}

void LOS_CAM_PWROff()
{
    STA_CIOMPCam.CMD = 0;
    LOS_EPS_Switch(17, SWITCH_OFF);
}